package org.yu.team2023.flashdays.command;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.commons.lang3.RandomUtils;
import org.yu.team2023.flashdays.FlashDays;
import org.yu.team2023.flashdays.ModUtil;
import org.yu.team2023.flashdays.ModItemTags;
import org.yu.team2023.flashdays.TreasureData;
import org.yu.team2023.flashdays.item.TreasureCurios;

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = FlashDays.MODID)
public class ModCommands {
    @SubscribeEvent
    public static void register(RegisterCommandsEvent event) {
        register(event.getDispatcher());
    }

    private static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
        dispatcher.register(Commands.literal(FlashDays.MODID).requires((stack) -> stack.hasPermission(2))
                        .then(Commands.literal("treasure")
                                .then(Commands.literal("levelup")
                                        .then(Commands.argument("target",EntityArgument.player())
                                                .then(Commands.argument("level",IntegerArgumentType.integer(1,14))
                                                        .executes(context -> {
                                                            ServerPlayer player = EntityArgument.getPlayer(context, "target");
                                                            int level = IntegerArgumentType.getInteger(context, "level");
                                                            ItemStack stack=player.getMainHandItem();
                                                            if(stack.is(ModItemTags.CURIOS_TREASURES)||stack.getItem() instanceof TreasureCurios){
                                                                TreasureData data=TreasureData.safeCreate(stack);
                                                                if(data!=null){
                                                                    for (int i = 0; i < level; i++) {
                                                                        data.upgrade();
                                                                    }
                                                                    data.save(stack);
                                                                }else {
                                                                    context.getSource().sendFailure(Component.translatable("msg.flashdays.treasure.upgrade.failed"));
                                                                    return 0;
                                                                }
                                                            }else {
                                                                context.getSource().sendFailure(Component.translatable("msg.flashdays.treasure.upgrade.failed"));
                                                                return 0;
                                                            }
                                                            return 1;
                                                        })
                                                )
                                        )
                                )
                        )
                .then(Commands.literal("randomTreasure").then(Commands.argument("target", EntityArgument.player())
                        .then(Commands.argument("level", IntegerArgumentType.integer(1, 15))
                                .executes(context -> {
                                    ServerPlayer player = EntityArgument.getPlayer(context, "target");
                                    int level = IntegerArgumentType.getInteger(context, "level");
                                    var itemStack = TreasureCurios.newInstance(ModUtil.randomSelect(ForgeRegistries.ITEMS
                                            .getValues().stream()
                                            .filter(item -> item instanceof TreasureCurios)
                                            .toList()));
                                    var treasure = new TreasureData(itemStack);
                                    for (int i = 0; i <
                                            Math.min(treasure.getQuality().getMaxLevel(), level-1); i++) {
                                        treasure.upgrade();
                                    }
                                    treasure.save(itemStack);
                                    player.addItem(itemStack);
                                    return 1;
                                }))
                        .executes(context -> {
                            ServerPlayer player = EntityArgument.getPlayer(context, "target");
                            player.addItem(TreasureCurios.newInstance(ModUtil.randomSelect(ForgeRegistries.ITEMS
                                    .getValues().stream()
                                    .filter(item -> item instanceof TreasureCurios)
                                    .toList())));
                            return 1;
                        })))
        );
    }
}
